using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common;
using Common.Enum;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Infragistics.UltraChart.Data.Series;
using Infragistics.UltraChart.Resources.Appearance;
using Infragistics.UltraChart.Shared.Events;
using Infragistics.UltraChart.Shared.Styles;
using Infragistics.Win;
using Infragistics.Win.UltraWinChart;
using Infragistics.Win.UltraWinToolTip;
using Microsoft.Win32;

namespace CustomChart
{
	/// <summary>
	/// 绘制图表的基类
	/// </summary>
	public abstract class BaseChart : IDisposable
	{
		public delegate void DelegateOnAxixRangeChangedEvent(object sender, EventArgs e);

		public delegate void DelegateOnChangeCurveStyleEvent(object sender, SelectedSeriesChangedArgs e);

		public delegate void DelegateOnClearHighLightSeriesEvent(object sender, EventArgs e);

		public delegate void DelegateOnSelectedSeriesChangedEvent(object sender, SelectedSeriesChangedArgs e);

		public delegate void DelegateOnGetTooltipsArgsEvent(object sender, GetTooltipsArgs e);

		public const string TooltipX = "#VAL{X}";

		public const string TooltipY = "#VALX{Y}";

		private const float _SplineTension = 0f;

		private const double marginTop = 13.0;

		private const double marginRight = 12.0;

		private const double marginMid = 0.0;

		protected UltraChart _Chart = new UltraChart();

		private bool _CanScale = true;

		private bool _ShowToolTips = true;

		private bool _IsDecrypt = true;

		private int _LineWidth = 3;

		private bool _CanChangeColor = true;

		private UltraToolTipManager mToolTipManager = new UltraToolTipManager();

		private MouseFigure figure = new MouseFigure();

		private BoxAnnotation boxAnnotation = new BoxAnnotation();

		private Graphics graphics;

		private bool isInDataItem;

		private bool _IsMouseDown;

		private List<XYSeriesEx> listSeriesRect = new List<XYSeriesEx>();

		private int margin = 2;

		protected List<ChartLayerAppearance> DataLineLayerList = new List<ChartLayerAppearance>();

		protected ChartLayerAppearance ScatterLayer;

		protected ChartLayerAppearance ScatterLayer2;

		protected ChartLayerAppearance ThresholdLayer;

		protected ChartLayerAppearance ScaleLayer;

		protected List<ChartLayerAppearance> HighLightLayerList = new List<ChartLayerAppearance>();

		protected ChartArea ChartArea = new ChartArea();

		protected AxisItem AxisX = new AxisItem();

		protected AxisItem AxisY = new AxisItem();

		private bool _IsCursomAxisValue;

		private double _MinX;

		private double _MaxX;

		private double _MinY;

		private double _MaxY;

		private double _LogMinY;

		private double marginLeft;

		private double marginBottom;

		private double lineWidth;

		private double lineHeigh;

		public ContextMenuStrip ContentMenu = new ContextMenuStrip();

		private PrinterSettings printer;

		private PageSettings page;

		private PrintDialog printdialog;

		private PrintDocument myPrintDoc;

		private string _TooltipsFromatX;

		private string _TooltipsFromatY;

		public UltraChart Chart
		{
			get
			{
				return _Chart;
			}
		}

		public string Name { get; set; }

		public bool CanScale
		{
			get
			{
				return _CanScale;
			}
			set
			{
				_CanScale = value;
			}
		}

		public bool ShowToolTips
		{
			get
			{
				return _ShowToolTips;
			}
			set
			{
				_ShowToolTips = value;
			}
		}

		public bool IsDecrypt
		{
			get
			{
				return _IsDecrypt;
			}
			set
			{
				_IsDecrypt = value;
			}
		}

		public int LineWidth
		{
			get
			{
				return _LineWidth;
			}
			set
			{
				_LineWidth = value;
				SetDataLayerLineWidth(value);
			}
		}

		public bool CanChangeColor
		{
			get
			{
				return _CanChangeColor;
			}
			set
			{
				_CanChangeColor = value;
			}
		}

		public ISeries SelectedSerie { get; set; }

		public bool IsCursomAxisValue
		{
			get
			{
				return _IsCursomAxisValue;
			}
			set
			{
				_IsCursomAxisValue = value;
			}
		}

		public double MinX
		{
			get
			{
				return _MinX;
			}
			set
			{
				if (!IsCursomAxisValue)
				{
					SetMinX(value);
				}
				_MinX = value;
			}
		}

		public double MaxX
		{
			get
			{
				return _MaxX;
			}
			set
			{
				if (!IsCursomAxisValue)
				{
					SetMaxX(value);
				}
				_MaxX = value;
			}
		}

		public double MinY
		{
			get
			{
				return _MinY;
			}
			set
			{
				if (!(value >= Math.Pow(10.0, 6.0)))
				{
					if (!IsCursomAxisValue)
					{
						SetMinY(value);
					}
					_MinY = value;
				}
			}
		}

		public double MaxY
		{
			get
			{
				return _MaxY;
			}
			set
			{
				if (!(value >= Math.Pow(10.0, 6.0)))
				{
					if (!IsCursomAxisValue)
					{
						SetMaxY(value);
					}
					_MaxY = value;
				}
			}
		}

		public double LogMinY
		{
			get
			{
				return _LogMinY;
			}
			set
			{
				_LogMinY = value;
			}
		}

		public string TooltipsFromatX
		{
			get
			{
				if (string.IsNullOrEmpty(_TooltipsFromatX))
				{
					return GetFormat(AxisX.Labels);
				}
				return _TooltipsFromatX;
			}
			set
			{
				_TooltipsFromatX = value;
			}
		}

		public string TooltipsFromatY
		{
			get
			{
				if (string.IsNullOrEmpty(_TooltipsFromatY))
				{
					return GetFormat(AxisY.Labels);
				}
				return _TooltipsFromatY;
			}
			set
			{
				_TooltipsFromatY = value;
			}
		}

		public event DelegateOnAxixRangeChangedEvent OnAxixRangeChanged;

		public event DelegateOnChangeCurveStyleEvent OnChangeCurveStyle;

		public event DelegateOnClearHighLightSeriesEvent OnClearHighLightSeries;

		public event DelegateOnSelectedSeriesChangedEvent OnSelectedSeriesChanged;

		public event DelegateOnGetTooltipsArgsEvent OnGetTooltipsArgs;

		private void RaiseAxixRangeChanged()
		{
			if (this.OnAxixRangeChanged != null)
			{
				OnAxixRangeChanged(this, EventArgs.Empty);
			}
		}

		private void RaiseChangeCurveStyle(SelectedSeriesChangedArgs args)
		{
			if (this.OnChangeCurveStyle != null)
			{
				OnChangeCurveStyle(this, args);
			}
		}

		private void RaiseClearHighLightSeries()
		{
			if (this.OnClearHighLightSeries != null)
			{
				this.OnClearHighLightSeries(this, new EventArgs());
			}
		}

		private void RaiseSelectedSeriesChanged(SelectedSeriesChangedArgs args)
		{
			if (this.OnSelectedSeriesChanged != null)
			{
				this.OnSelectedSeriesChanged(this, args);
			}
		}

		private void RaiseGetTooltips(GetTooltipsArgs args)
		{
			if (this.OnGetTooltipsArgs != null)
			{
				this.OnGetTooltipsArgs(this, args);
			}
		}

		public BaseChart()
		{
			InitControl();
			mToolTipManager.AutoPopDelay = 8000;
			mToolTipManager.InitialDelay = 500;
			mToolTipManager.ToolTipTextStyle = ToolTipTextStyle.Formatted;
			figure.DistanceThreshold = 3.0;
		}

		private void _Chart_MouseLeave(object sender, EventArgs e)
		{
			if (!ContentMenu.Visible)
			{
				RaiseClearHighLightSeries();
			}
		}

		protected virtual void Chart_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left || !CanScale || !IsAxisYLinear())
			{
				return;
			}
			_IsMouseDown = true;
			if (listSeriesRect.Count == 0)
			{
				for (int i = 0; i < 4; i++)
				{
					XYSeriesEx xYSeriesEx = new XYSeriesEx();
					xYSeriesEx.PEs.Add(new PaintElement());
					xYSeriesEx.PEs[0].Fill = System.Drawing.Color.Black;
					listSeriesRect.Add(xYSeriesEx);
					ScaleLayer.Series.Add(xYSeriesEx);
				}
			}
			foreach (XYSeriesEx item in listSeriesRect)
			{
				item.Points.Clear();
				item.Points.Add(new XYDataPoint(TransformXToData(e.Location.X), TransformYToData(e.Location.Y), "", false));
				item.Points.Add(new XYDataPoint(TransformXToData(e.Location.X), TransformYToData(e.Location.Y), "", false));
			}
			ScaleLayer.Visible = true;
		}

		protected virtual void Chart_MouseUp(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left && CanScale && _IsMouseDown)
			{
				_IsMouseDown = false;
				double valueX = listSeriesRect[0].Points[0].ValueX;
				double valueX2 = listSeriesRect[3].Points[1].ValueX;
				double valueY = listSeriesRect[3].Points[1].ValueY;
				double valueY2 = listSeriesRect[0].Points[0].ValueY;
				if (valueX2 > valueX && valueY2 > valueY)
				{
					SetMinX(valueX);
					SetMaxX(valueX2);
					SetMinY(valueY);
					SetMaxY(valueY2);
					IsCursomAxisValue = true;
				}
				else if (valueX > valueX2 && valueY > valueY2)
				{
					RestoreAxisZoom();
				}
				listSeriesRect[0].Visible = false;
				listSeriesRect[1].Visible = false;
				listSeriesRect[2].Visible = false;
				listSeriesRect[3].Visible = false;
				ScaleLayer.Visible = false;
			}
			if (e.Button == MouseButtons.Right)
			{
				Point point = _Chart.PointToScreen(new Point(e.X, e.Y));
				ContentMenu.Show(point.X, point.Y);
			}
		}

		protected virtual void Chart_MouseMove(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left && CanScale && _IsMouseDown)
			{
				double valueX = TransformXToData(e.Location.X);
				double valueY = TransformYToData(e.Location.Y);
				listSeriesRect[0].Visible = false;
				listSeriesRect[1].Visible = false;
				listSeriesRect[2].Visible = false;
				listSeriesRect[3].Visible = false;
				listSeriesRect[0].Points[1].ValueX = valueX;
				listSeriesRect[1].Points[1].ValueY = valueY;
				listSeriesRect[2].Points[0].ValueY = valueY;
				listSeriesRect[2].Points[1].ValueX = valueX;
				listSeriesRect[2].Points[1].ValueY = valueY;
				listSeriesRect[3].Points[0].ValueX = valueX;
				listSeriesRect[3].Points[1].ValueX = valueX;
				listSeriesRect[3].Points[1].ValueY = valueY;
				listSeriesRect[0].Visible = true;
				listSeriesRect[1].Visible = true;
				listSeriesRect[2].Visible = true;
				listSeriesRect[3].Visible = true;
			}
			else if (!isInDataItem)
			{
				Point location = e.Location;
				ISeries series = null;
				if (IsAxisYLinear())
				{
					series = figure.SelectCurve(new Point
					{
						X = (int)TransformXToRelative(location.X),
						Y = (int)TransformYToRelative(location.Y)
					});
				}
				SelectedSeries(series);
			}
		}

		private void Chart_DataItemOver(object sender, ChartDataEventArgs e)
		{
			if (!_IsMouseDown && !ScaleLayer.Series.Contains(e.Primitive.Series) && !ThresholdLayer.Series.Contains(e.Primitive.Series))
			{
				isInDataItem = true;
				SelectedSeries(e.Primitive.Series);
				RaiseSelectedSeriesTooltips(e.Primitive.DataPoint as XYDataPoint);
			}
		}

		private void Chart_DataItemOut(object sender, ChartDataEventArgs e)
		{
			if (!_IsMouseDown)
			{
				isInDataItem = false;
				mToolTipManager.HideToolTip();
				mToolTipManager.Enabled = false;
			}
		}

		private void Chart_SizeChanged(object sender, EventArgs e)
		{
			RefreshXMargin();
			RefreshYMargin();
			RefreshAxisXInterval();
			RefreshAxisYInterval();
		}

		private void InitControl()
		{
			boxAnnotation.TextStyle.Font = new System.Drawing.Font("Arial,SimSun", 8f);
			boxAnnotation.TextStyle.HorizontalAlign = StringAlignment.Near;
			boxAnnotation.Location.Type = LocationType.Pixels;
			boxAnnotation.Visible = false;
			_Chart.Annotations.Add(boxAnnotation);
			_Chart.Border.Thickness = 0;
			_Chart.Dock = DockStyle.Fill;
			_Chart.SmoothingMode = SmoothingMode.AntiAlias;
			_Chart.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			InitMenu();
			InitToolTips();
			_Chart.LabelHash = new Hashtable();
			_Chart.ChartType = ChartType.Composite;
			InitTitle();
			InitChartArea();
			InitAxisX();
			InitAxisY();
			InitAxixTopRight();
			InitNullLayer();
			InitScatterLayer();
			InitScatterLayer2();
			InitThresholdLayer();
			InitScaleLayer();
			RegsiterEvent();
			graphics = Chart.CreateGraphics();
		}

		private void RegsiterEvent()
		{
			_Chart.SizeChanged += Chart_SizeChanged;
			_Chart.DataItemOut += Chart_DataItemOut;
			_Chart.DataItemOver += Chart_DataItemOver;
			_Chart.MouseDown += Chart_MouseDown;
			_Chart.MouseMove += Chart_MouseMove;
			_Chart.MouseUp += Chart_MouseUp;
			_Chart.MouseLeave += _Chart_MouseLeave;
		}

		private void InitToolTips()
		{
			_Chart.Tooltips.Display = TooltipDisplay.Never;
		}

		private void InitTitle()
		{
			_Chart.TitleLeft.VerticalAlign = StringAlignment.Center;
			_Chart.TitleLeft.HorizontalAlign = StringAlignment.Center;
			_Chart.TitleLeft.Margins.Bottom = margin;
			_Chart.TitleLeft.Margins.Left = margin;
			_Chart.TitleLeft.Margins.Right = margin;
			_Chart.TitleLeft.Margins.Top = margin;
			_Chart.TitleLeft.Text = "Y轴";
			_Chart.TitleLeft.Visible = true;
			_Chart.TitleBottom.VerticalAlign = StringAlignment.Center;
			_Chart.TitleBottom.HorizontalAlign = StringAlignment.Center;
			_Chart.TitleBottom.Margins.Bottom = margin;
			_Chart.TitleBottom.Margins.Left = margin;
			_Chart.TitleBottom.Margins.Right = margin;
			_Chart.TitleBottom.Margins.Top = margin;
			_Chart.TitleBottom.Text = "X轴";
			_Chart.TitleBottom.Visible = true;
			_Chart.TitleRight.Visible = false;
			_Chart.TitleTop.Visible = false;
		}

		private void InitNullLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.ConnectWithLines = false;
			scatterChartAppearance.Icon = SymbolIcon.None;
			scatterChartAppearance.IconSize = SymbolIconSize.Small;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 1;
			XYSeries xYSeries = new XYSeries();
			xYSeries.Points.Add(new XYDataPoint(-1000.0, -1000.0, "", false));
			chartLayerAppearance.Series.Add(xYSeries);
			_Chart.CompositeChart.ChartLayers.Add(chartLayerAppearance);
		}

		private void InitScaleLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			chartLayerAppearance.Visible = false;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.ConnectWithLines = true;
			scatterChartAppearance.Icon = SymbolIcon.None;
			scatterChartAppearance.IconSize = SymbolIconSize.Small;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 2;
			ScaleLayer = chartLayerAppearance;
			_Chart.CompositeChart.ChartLayers.Add(chartLayerAppearance);
		}

		private void InitThresholdLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.ConnectWithLines = true;
			scatterChartAppearance.Icon = SymbolIcon.None;
			scatterChartAppearance.IconSize = SymbolIconSize.Small;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 3;
			ThresholdLayer = chartLayerAppearance;
			_Chart.CompositeChart.ChartLayers.Add(chartLayerAppearance);
		}

		private void InitScatterLayer()
		{
			ScatterLayer = CreateNewScatterLayer();
			_Chart.CompositeChart.ChartLayers.Add(ScatterLayer);
		}

		private void InitScatterLayer2()
		{
			ScatterLayer2 = CreateNewScatterLayer();
			_Chart.CompositeChart.ChartLayers.Add(ScatterLayer2);
		}

		private ChartLayerAppearance CreateNewScatterLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.ConnectWithLines = false;
			scatterChartAppearance.Icon = SymbolIcon.Circle;
			scatterChartAppearance.IconSize = SymbolIconSize.Small;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 3;
			scatterChartAppearance.CharacterFont = new System.Drawing.Font(scatterChartAppearance.CharacterFont.Name, 15f, FontStyle.Bold);
			return chartLayerAppearance;
		}

		private ChartLayerAppearance CreateNewDataLineLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.ConnectWithLines = true;
			scatterChartAppearance.Icon = SymbolIcon.None;
			scatterChartAppearance.IconSize = SymbolIconSize.Small;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 3;
			return chartLayerAppearance;
		}

		protected ChartLayerAppearance CreateNewLayer()
		{
			ChartLayerAppearance chartLayerAppearance = new ChartLayerAppearance();
			chartLayerAppearance.ChartArea = ChartArea;
			chartLayerAppearance.AxisX = AxisX;
			chartLayerAppearance.AxisY = AxisY;
			return chartLayerAppearance;
		}

		private void SetDataLayerLineWidth(int width)
		{
			foreach (ChartLayerAppearance dataLineLayer in DataLineLayerList)
			{
				((ScatterChartAppearance)dataLineLayer.ChartTypeAppearance).LineAppearance.Thickness = width;
			}
		}

		private void InitChartArea()
		{
			ChartArea.Border.Thickness = 0;
			_Chart.CompositeChart.ChartAreas.Add(ChartArea);
		}

		protected virtual void InitAxisX()
		{
			AxisX.OrientationType = AxisNumber.X_Axis;
			AxisX.DataType = AxisDataType.Numeric;
			AxisX.Labels.Layout.Behavior = AxisLabelLayoutBehaviors.UseCollection;
			AxisX.Labels.Layout.BehaviorCollection.Add(new FontScalingAxisLabelLayoutBehavior
			{
				Enabled = true
			});
			AxisX.Labels.Layout.Padding = 3;
			AxisX.Labels.HorizontalAlign = StringAlignment.Far;
			AxisX.Labels.VerticalAlign = StringAlignment.Far;
			AxisX.Labels.Orientation = TextOrientation.Horizontal;
			AxisX.LineThickness = 1;
			AxisX.Labels.ItemFormat = AxisItemLabelFormat.Custom;
			AxisX.Labels.ItemFormatString = "<DATA_VALUE:0>";
			AxisX.TickmarkStyle = AxisTickStyle.DataInterval;
			AxisX.RangeType = AxisRangeType.Custom;
			AxisX.RangeMin = 1.0;
			AxisX.RangeMax = 40.0;
			CustomAxisX();
			_Chart.CompositeChart.ChartAreas[0].Axes.Add(AxisX);
		}

		public void SetAxixXToIntTickMark(bool intTickMark)
		{
			AxisX.TickmarkStyle = ((!intTickMark) ? AxisTickStyle.Percentage : AxisTickStyle.DataInterval);
		}

		protected virtual void CustomAxisX()
		{
		}

		private void InitAxisY()
		{
			AxisY.OrientationType = AxisNumber.Y_Axis;
			AxisY.DataType = AxisDataType.Numeric;
			AxisY.Labels.Layout.Behavior = AxisLabelLayoutBehaviors.UseCollection;
			AxisY.Labels.Layout.BehaviorCollection.Add(new FontScalingAxisLabelLayoutBehavior
			{
				Enabled = true
			});
			AxisY.Labels.Layout.Padding = 2;
			AxisY.Labels.HorizontalAlign = StringAlignment.Far;
			AxisY.Labels.VerticalAlign = StringAlignment.Far;
			AxisY.Labels.Orientation = TextOrientation.Horizontal;
			AxisY.LineThickness = 1;
			AxisY.Labels.ItemFormat = AxisItemLabelFormat.Custom;
			AxisY.Labels.ItemFormatString = "<DATA_VALUE:0>";
			AxisY.RangeType = AxisRangeType.Custom;
			AxisY.RangeMin = 0.0;
			AxisY.RangeMax = 1.0;
			AxisY.LogBase = 10.0;
			CustomAxisY();
			_Chart.CompositeChart.ChartAreas[0].Axes.Add(AxisY);
		}

		public void SetAxisYLinear(bool linear)
		{
			AxisY.NumericAxisType = ((!linear) ? NumericAxisType.Logarithmic : NumericAxisType.Linear);
			if (!linear)
			{
				IsCursomAxisValue = false;
			}
		}

		public bool IsAxisYLinear()
		{
			return AxisY.NumericAxisType == NumericAxisType.Linear;
		}

		protected virtual void CustomAxisY()
		{
		}

		private void InitAxixTopRight()
		{
			AxisItem axisItem = new AxisItem();
			axisItem.Extent = 0;
			axisItem.LineThickness = 1;
			axisItem.OrientationType = AxisNumber.X2_Axis;
			axisItem.Labels.Visible = false;
			axisItem.MajorGridLines.Visible = false;
			axisItem.MinorGridLines.Visible = false;
			_Chart.CompositeChart.ChartAreas[0].Axes.Add(axisItem);
			axisItem = new AxisItem();
			axisItem.Extent = 4;
			axisItem.LineThickness = 1;
			axisItem.OrientationType = AxisNumber.Y2_Axis;
			axisItem.Labels.Visible = false;
			axisItem.MajorGridLines.Visible = false;
			axisItem.MinorGridLines.Visible = false;
			_Chart.CompositeChart.ChartAreas[0].Axes.Add(axisItem);
		}

		public void RestoreAxisZoom()
		{
			IsCursomAxisValue = false;
			MinX = MinX;
			MaxX = MaxX;
			MinY = MinY;
			MaxY = MaxY;
			RefreshAxisYInterval();
		}

		private double Format(double value, string format)
		{
			double result = value;
			string s = value.ToString(format);
			double.TryParse(s, out result);
			return result;
		}

		internal bool SetMinX(double value)
		{
			AxisX.RangeMin = ((AxisX.TickmarkStyle == AxisTickStyle.DataInterval) ? Math.Floor(Format(value, GetXFormat())) : Format(value, GetXFormat()));
			figure.Xmin = AxisX.RangeMin;
			RefreshAxisXInterval();
			RefreshXMargin();
			RaiseAxixRangeChanged();
			return true;
		}

		internal bool SetMaxX(double value)
		{
			AxisX.RangeMax = ((AxisX.TickmarkStyle == AxisTickStyle.DataInterval) ? Math.Ceiling(Format(value, GetYFormat())) : Format(value, GetYFormat()));
			figure.Xmax = AxisX.RangeMax;
			RefreshAxisXInterval();
			RefreshXMargin();
			RaiseAxixRangeChanged();
			return true;
		}

		internal bool SetMinY(double value)
		{
			if (!IsAxisYLinear() && value < LogMinY)
			{
				value = LogMinY;
			}
			AxisY.RangeMin = value;
			figure.Ymin = value;
			RefreshYMargin();
			RaiseAxixRangeChanged();
			return true;
		}

		internal bool SetMaxY(double value)
		{
			AxisY.RangeMax = value;
			figure.Ymax = value;
			RefreshYMargin();
			RaiseAxixRangeChanged();
			return true;
		}

		public double GetCurrentMaxX()
		{
			return AxisX.RangeMax;
		}

		public double GetCurrentMinX()
		{
			return AxisX.RangeMin;
		}

		public double GetCurrentMaxY()
		{
			return AxisY.RangeMax;
		}

		public double GetCurrentMinY()
		{
			return AxisY.RangeMin;
		}

		protected double GetAxisXInterval()
		{
			double result = 1.0;
			Graphics graphics = _Chart.CreateGraphics();
			string format = GetFormat(AxisX.Labels);
			string text = AxisX.RangeMax.ToString(format);
			string text2 = AxisX.RangeMin.ToString(format);
			double num = graphics.MeasureString(text, AxisX.Labels.Font).Width;
			double num2 = graphics.MeasureString(text2, AxisX.Labels.Font).Width;
			double num3 = ((num > num2) ? num : num2);
			int num4 = (int)(lineWidth / num3) - 1;
			int num5 = (int)Math.Floor(AxisX.RangeMax - AxisX.RangeMin);
			if (num4 >= num5)
			{
				result = 1.0;
			}
			else if (num4 >= num5 / 2)
			{
				result = 2.0;
			}
			else if (num4 >= num5 / 5)
			{
				result = 5.0;
			}
			else if (num4 >= num5 / 10)
			{
				result = 10.0;
			}
			else if (num4 >= num5 / 20)
			{
				result = 20.0;
			}
			graphics.Dispose();
			return result;
		}

		public virtual void RefreshAxisXInterval()
		{
			if (AxisX.TickmarkStyle == AxisTickStyle.DataInterval)
			{
				AxisX.TickmarkInterval = GetAxisXInterval();
			}
			else if (AxisX.TickmarkStyle == AxisTickStyle.Percentage)
			{
				Graphics graphics = _Chart.CreateGraphics();
				string format = GetFormat(AxisX.Labels);
				string text = AxisX.RangeMax.ToString(format);
				string text2 = AxisX.RangeMin.ToString(format);
				double num = graphics.MeasureString(text, AxisX.Labels.Font).Height;
				double num2 = graphics.MeasureString(text2, AxisX.Labels.Font).Height;
				double num3 = ((num > num2) ? num : num2);
				int num4 = (int)(lineHeigh / num3) - 1;
				if (num4 >= 10)
				{
					AxisX.TickmarkPercentage = 10.0;
				}
				else if (num4 >= 5)
				{
					AxisX.TickmarkPercentage = 20.0;
				}
				else if (num4 >= 2)
				{
					AxisX.TickmarkPercentage = 50.0;
				}
				else
				{
					AxisX.TickmarkPercentage = 100.0;
				}
				graphics.Dispose();
			}
		}

		public void RefreshAxisYInterval()
		{
			if (IsAxisYLinear())
			{
				Graphics graphics = _Chart.CreateGraphics();
				string format = GetFormat(AxisY.Labels);
				string text = AxisY.RangeMax.ToString(format);
				string text2 = AxisY.RangeMin.ToString(format);
				double num = graphics.MeasureString(text, AxisY.Labels.Font).Height;
				double num2 = graphics.MeasureString(text2, AxisY.Labels.Font).Height;
				double num3 = ((num > num2) ? num : num2);
				int num4 = (int)(lineHeigh / num3) - 1;
				if (num4 >= 10)
				{
					AxisY.TickmarkPercentage = 10.0;
				}
				else if (num4 >= 5)
				{
					AxisY.TickmarkPercentage = 20.0;
				}
				else if (num4 >= 2)
				{
					AxisY.TickmarkPercentage = 50.0;
				}
				else
				{
					AxisY.TickmarkPercentage = 100.0;
				}
				graphics.Dispose();
			}
			else
			{
				double num5 = Math.Log10(GetCurrentMaxY() / GetCurrentMinY());
				AxisY.TickmarkPercentage = Math.Min(100.0, 100.0 / num5);
			}
		}

		public double GetDrawLayoutWidth()
		{
			return lineWidth;
		}

		private void RefreshXMargin()
		{
			Graphics graphics = _Chart.CreateGraphics();
			double num = graphics.MeasureString("-123456.7", AxisY.Labels.Font).Width;
			AxisY.Extent = (int)num + margin;
			_Chart.TitleLeft.Extent = (int)graphics.MeasureString(_Chart.TitleLeft.Text, _Chart.TitleLeft.Font).Height + margin * 2;
			marginLeft = (double)(AxisY.Extent + _Chart.TitleLeft.Extent) + 0.0 - (double)AxisY.Labels.Layout.Padding - 5.0;
			lineWidth = (double)_Chart.Width - marginLeft - 12.0;
			figure.XPixel = lineWidth;
			graphics.Dispose();
		}

		private void RefreshYMargin()
		{
			Graphics graphics = _Chart.CreateGraphics();
			_Chart.TitleBottom.Extent = (int)graphics.MeasureString(_Chart.TitleBottom.Text, _Chart.TitleBottom.Font).Height + margin * 2;
			AxisX.Extent = _Chart.TitleBottom.Extent + margin;
			marginBottom = (double)(AxisX.Extent + _Chart.TitleBottom.Extent) + 0.0 - (double)AxisX.Labels.Layout.Padding - 5.0;
			lineHeigh = (double)_Chart.Height - marginBottom - 13.0;
			figure.YPixel = lineHeigh;
			graphics.Dispose();
		}

		protected virtual string GetFormat(AxisLabelAppearance labels)
		{
			string itemFormatString = labels.ItemFormatString;
			itemFormatString = itemFormatString.Replace("<", "");
			itemFormatString = itemFormatString.Replace("DATA_VALUE", "");
			itemFormatString = itemFormatString.Replace(":", "");
			return itemFormatString.Replace(">", "");
		}

		protected virtual string FormatX(double value)
		{
			return value.ToString(GetFormat(AxisX.Labels));
		}

		protected virtual string FormatY(double value)
		{
			return value.ToString(GetFormat(AxisY.Labels));
		}

		public double TransformXToRelative(double position)
		{
			return position - marginLeft;
		}

		public double TransformYToRelative(double position)
		{
			return lineHeigh - position + 13.0;
		}

		public double TransformXToData(double position)
		{
			position = TransformXToRelative(position);
			return (AxisX.RangeMax - AxisX.RangeMin) * position / lineWidth + AxisX.RangeMin;
		}

		public double TransformYToData(double position)
		{
			position = TransformYToRelative(position);
			return (AxisY.RangeMax - AxisY.RangeMin) * position / lineHeigh + AxisY.RangeMin;
		}

		public string TransformXToString(double position)
		{
			return TransformXToData(position).ToString(GetFormat(AxisX.Labels));
		}

		public string TransformYToString(double position)
		{
			return TransformYToData(position).ToString(GetFormat(AxisY.Labels));
		}

		public void AutoSizeAxis(double ratioY)
		{
			if (!IsAxisYLinear())
			{
				return;
			}
			double num = double.NaN;
			double num2 = double.NaN;
			double num3 = double.NaN;
			double num4 = double.NaN;
			foreach (ChartLayerAppearance dataLineLayer in DataLineLayerList)
			{
				foreach (XYSeries item in dataLineLayer.Series)
				{
					if (item.Points.Count != 0)
					{
						double num5 = (from XYDataPoint s in item.Points
							select s.ValueX).Min();
						if (double.IsNaN(num) || num > num5)
						{
							num = num5;
						}
						num5 = (from XYDataPoint s in item.Points
							select s.ValueX).Max();
						if (double.IsNaN(num2) || num2 < num5)
						{
							num2 = num5;
						}
						num5 = (from XYDataPoint s in item.Points
							select s.ValueY).Min();
						if (double.IsNaN(num3) || num3 > num5)
						{
							num3 = num5;
						}
						num5 = (from XYDataPoint s in item.Points
							select s.ValueY).Max();
						if (double.IsNaN(num4) || num4 < num5)
						{
							num4 = num5;
						}
					}
				}
			}
			if (!double.IsNaN(num) && !double.IsNaN(num2))
			{
				MinX = num;
				MaxX = num2;
			}
			if (!double.IsNaN(num3) && !double.IsNaN(num4))
			{
				double num6 = (ratioY - 1.0) * (num4 - num3);
				MinY = num3 - num6;
				MaxY = num4 + num6;
			}
		}

		public void ChangeSeriesIcon(ISeries series, ESeriesType icon)
		{
			ChartLayerAppearance chartLayerAppearance = DataLineLayerList.Where((ChartLayerAppearance s) => s.Series[0] == series).FirstOrDefault();
			if (chartLayerAppearance != null && chartLayerAppearance.ChartTypeAppearance is ScatterChartAppearance)
			{
				SetSeriesSymbolIcon((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance, icon);
			}
		}

		public int AddDataSeries(ISeries series, ESeriesType icon = ESeriesType.None)
		{
			figure.Series.Add(series);
			ChartLayerAppearance chartLayerAppearance = CreateNewDataLineLayer();
			SetSeriesSymbolIcon((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance, icon);
			chartLayerAppearance.Series.Add(series);
			DataLineLayerList.Add(chartLayerAppearance);
			_Chart.CompositeChart.ChartLayers.Insert(0, chartLayerAppearance);
			return 0;
		}

		private void SetSeriesSymbolIcon(ScatterChartAppearance sca, ESeriesType type)
		{
			switch (type)
			{
			case ESeriesType.None:
				sca.Icon = SymbolIcon.None;
				sca.IconSize = SymbolIconSize.Small;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Solid;
				break;
			case ESeriesType.Circle:
				sca.Icon = SymbolIcon.Circle;
				sca.IconSize = SymbolIconSize.Medium;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Solid;
				break;
			case ESeriesType.Square:
				sca.Icon = SymbolIcon.Square;
				sca.IconSize = SymbolIconSize.Medium;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Solid;
				break;
			case ESeriesType.Triangle:
				sca.Icon = SymbolIcon.Triangle;
				sca.IconSize = SymbolIconSize.Medium;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Solid;
				break;
			case ESeriesType.X:
				sca.Icon = SymbolIcon.X;
				sca.IconSize = SymbolIconSize.Medium;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Solid;
				break;
			case ESeriesType.Dotted:
				sca.Icon = SymbolIcon.None;
				sca.IconSize = SymbolIconSize.Small;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Dot;
				break;
			case ESeriesType.Dashed:
				sca.Icon = SymbolIcon.None;
				sca.IconSize = SymbolIconSize.Small;
				sca.LineAppearance.DrawStyle = LineDrawStyle.Dash;
				break;
			case ESeriesType.DashDot:
				sca.Icon = SymbolIcon.None;
				sca.IconSize = SymbolIconSize.Small;
				sca.LineAppearance.DrawStyle = LineDrawStyle.DashDot;
				break;
			}
		}

		public void AddDataSeriesRange(ISeries[] items, ESeriesType icon = ESeriesType.None)
		{
			foreach (ISeries series in items)
			{
				AddDataSeries(series, icon);
			}
		}

		public void RemoveDataSeries(ISeries series)
		{
			figure.Series.Remove(series);
			foreach (ChartLayerAppearance dataLineLayer in DataLineLayerList)
			{
				if (dataLineLayer.Series.Count == 1 && dataLineLayer.Series[0] == series)
				{
					DataLineLayerList.Remove(dataLineLayer);
					_Chart.CompositeChart.ChartLayers.Remove(dataLineLayer);
					break;
				}
			}
		}

		public void ClearAllDataSeries()
		{
			foreach (ChartLayerAppearance dataLineLayer in DataLineLayerList)
			{
				figure.Series.Remove(dataLineLayer.Series[0]);
				_Chart.CompositeChart.ChartLayers.Remove(dataLineLayer);
			}
			DataLineLayerList.Clear();
		}

		public void SetScatterIconSize(SymbolIcon icon = SymbolIcon.None, SymbolIconSize size = SymbolIconSize.Auto, char character = 'A')
		{
			((ScatterChartAppearance)ScatterLayer.ChartTypeAppearance).Icon = icon;
			((ScatterChartAppearance)ScatterLayer.ChartTypeAppearance).IconSize = size;
			((ScatterChartAppearance)ScatterLayer.ChartTypeAppearance).Character = character;
		}

		public int AddScatterSeries(ISeries series)
		{
			if (ScatterLayer.Series.Contains(series))
			{
				return 0;
			}
			return ScatterLayer.Series.Add(series);
		}

		public void ClearAllScatterSeries()
		{
			ScatterLayer.Series.Clear();
		}

		public void SetScatter2IconSize(SymbolIcon icon = SymbolIcon.None, SymbolIconSize size = SymbolIconSize.Auto, char character = 'A')
		{
			((ScatterChartAppearance)ScatterLayer2.ChartTypeAppearance).Icon = icon;
			((ScatterChartAppearance)ScatterLayer2.ChartTypeAppearance).IconSize = size;
			((ScatterChartAppearance)ScatterLayer2.ChartTypeAppearance).Character = character;
		}

		public int AddScatter2Series(ISeries series)
		{
			if (ScatterLayer2.Series.Contains(series))
			{
				return 0;
			}
			return ScatterLayer2.Series.Add(series);
		}

		public void ClearAllScatter2Series()
		{
			ScatterLayer2.Series.Clear();
		}

		public int AddThresholdSeries(ISeries series)
		{
			figure.Series.Add(series);
			return ThresholdLayer.Series.Add(series);
		}

		public void AddThresholdSeriesRange(ISeries[] items)
		{
			figure.Series.AddRange(items);
			ThresholdLayer.Series.AddRange(items);
		}

		public void ClearAllThresholdSeries()
		{
			foreach (ISeries item in ThresholdLayer.Series)
			{
				figure.Series.Remove(item);
			}
			ThresholdLayer.Series.Clear();
		}

		public void ClearAllSeries()
		{
			ClearAllDataSeries();
			ClearAllThresholdSeries();
			ClearAllScatterSeries();
		}

		private ChartLayerAppearance CreateHighLightLayer()
		{
			ChartLayerAppearance chartLayerAppearance = CreateNewLayer();
			chartLayerAppearance.ChartType = ChartType.ScatterChart;
			ScatterChartAppearance scatterChartAppearance = (ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance;
			scatterChartAppearance.LineAppearance.SplineTension = 0f;
			scatterChartAppearance.LineAppearance.Thickness = 5;
			return chartLayerAppearance;
		}

		public void ClearHighLightSeries()
		{
			foreach (ChartLayerAppearance highLightLayer in HighLightLayerList)
			{
				highLightLayer.Series.Clear();
				_Chart.CompositeChart.ChartLayers.Remove(highLightLayer);
			}
			HighLightLayerList.Clear();
		}

		public void AddHighLightSeries(XYSeries series, bool highLight = true)
		{
			ChartLayerAppearance chartLayerAppearance = HighLightLayerList.Where((ChartLayerAppearance s) => s.Series[0] == series).FirstOrDefault();
			if (highLight)
			{
				if (chartLayerAppearance == null)
				{
					chartLayerAppearance = CreateHighLightLayer();
				}
				ChartLayerAppearance chartLayerAppearance2 = DataLineLayerList.Where((ChartLayerAppearance s) => s.Series[0] == series).FirstOrDefault();
				if (chartLayerAppearance2 != null && chartLayerAppearance2.ChartTypeAppearance is ScatterChartAppearance)
				{
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).ConnectWithLines = ((ScatterChartAppearance)chartLayerAppearance2.ChartTypeAppearance).ConnectWithLines;
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).Icon = ((ScatterChartAppearance)chartLayerAppearance2.ChartTypeAppearance).Icon;
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).IconSize = ((ScatterChartAppearance)chartLayerAppearance2.ChartTypeAppearance).IconSize;
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).LineAppearance.DrawStyle = ((ScatterChartAppearance)chartLayerAppearance2.ChartTypeAppearance).LineAppearance.DrawStyle;
				}
				if (chartLayerAppearance2 == null && series.Points.Count == 1)
				{
					chartLayerAppearance2 = ScatterLayer;
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).Icon = ((ScatterChartAppearance)chartLayerAppearance2.ChartTypeAppearance).Icon;
					((ScatterChartAppearance)chartLayerAppearance.ChartTypeAppearance).IconSize = SymbolIconSize.Medium;
				}
				if (chartLayerAppearance2 != null)
				{
					chartLayerAppearance.Series.Add(series);
					_Chart.CompositeChart.ChartLayers.Add(chartLayerAppearance);
					HighLightLayerList.Add(chartLayerAppearance);
				}
			}
			else if (chartLayerAppearance != null)
			{
				chartLayerAppearance.Series.Remove(series);
				_Chart.CompositeChart.ChartLayers.Remove(chartLayerAppearance);
				HighLightLayerList.Remove(chartLayerAppearance);
			}
		}

		public ISeries[] GetHighLightSreis()
		{
			return (from s in HighLightLayerList
				where s.Series.Count > 0
				select s.Series[0]).ToArray();
		}

		protected virtual void CustomMenu()
		{
		}

		private void InitMenu()
		{
			ContentMenu.Opening += menu_Opening;
			ContentMenu.Closed += menu_Closed;
			ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem();
			toolStripMenuItem.Text = Utility.GetMessage("axis_zoom_restore");
			toolStripMenuItem.Click += AxisZoomRestore_Click;
			ContentMenu.Items.Add(toolStripMenuItem);
			ContentMenu.Items.Add(new ToolStripSeparator());
			toolStripMenuItem = new ToolStripMenuItem();
			toolStripMenuItem.Text = Utility.GetMessage("save_image");
			toolStripMenuItem.Click += SaveImage_Click;
			ContentMenu.Items.Add(toolStripMenuItem);
			toolStripMenuItem = new ToolStripMenuItem();
			toolStripMenuItem.Text = Utility.GetMessage("copy_to_clipboard");
			toolStripMenuItem.Click += CopyToClipboard_Click;
			ContentMenu.Items.Add(toolStripMenuItem);
			toolStripMenuItem = new ToolStripMenuItem();
			toolStripMenuItem.Text = Utility.GetMessage("copy_curve");
			toolStripMenuItem.Click += Print_Click;
			ContentMenu.Items.Add(toolStripMenuItem);
			CustomMenu();
		}

		public void InsertMenuItem(int index, ToolStripMenuItem item)
		{
			if (index < 0 || index >= ContentMenu.Items.Count)
			{
				ContentMenu.Items.Add(item);
			}
			else
			{
				ContentMenu.Items.Insert(index, item);
			}
		}

		public void AddMenuItem(ToolStripMenuItem item)
		{
			ContentMenu.Items.Add(item);
		}

		protected virtual void menu_Opening(object sender, CancelEventArgs e)
		{
		}

		private void AxisZoomRestore_Click(object sender, EventArgs e)
		{
			RestoreAxisZoom();
		}

		private void menu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
		{
			RaiseClearHighLightSeries();
		}

		protected virtual void CopyCurveData_Click(object sender, EventArgs e)
		{
			if (SelectedSerie == null)
			{
				return;
			}
			XYSeriesEx xYSeriesEx = SelectedSerie as XYSeriesEx;
			if (xYSeriesEx == null)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < xYSeriesEx.Points.Count; i++)
			{
				stringBuilder.Append(xYSeriesEx.Points[i].ValueX);
				if (i != xYSeriesEx.Points.Count - 1)
				{
					stringBuilder.Append("\t");
				}
			}
			stringBuilder.AppendLine(string.Empty);
			for (int j = 0; j < xYSeriesEx.Points.Count; j++)
			{
				stringBuilder.Append(xYSeriesEx.Points[j].ValueY);
				if (j != xYSeriesEx.Points.Count - 1)
				{
					stringBuilder.Append("\t");
				}
			}
			SLANClipboard.SetToClipboard(stringBuilder.ToString());
		}

		protected void ExportCurveToExcel_Click(object sender, EventArgs e)
		{
			System.Windows.Forms.SaveFileDialog saveFileDialog = new System.Windows.Forms.SaveFileDialog();
			saveFileDialog.Title = Utility.GetMessage("Save");
			saveFileDialog.Filter = string.Format("{1}{0}|*.{2}|{3}{0}|*.{3}|{4}{0}|*.{4}", Utility.GetMessage("File"), "Excel", "xlsx", "csv", "txt");
			saveFileDialog.FileName = Name;
			saveFileDialog.FilterIndex = 1;
			saveFileDialog.InitialDirectory = Utility.GetExperimentPath();
			if (saveFileDialog.ShowDialog() == DialogResult.OK)
			{
				_Chart.Cursor = Cursors.WaitCursor;
				List<XYSeriesEx> seriesList = (from XYSeriesEx s in DataLineLayerList.Select((ChartLayerAppearance s) => s.Series[0])
					where s.Visible
					select s).ToList();
				switch (saveFileDialog.FilterIndex)
				{
				case 1:
					SaveToExcel(saveFileDialog.FileName, seriesList);
					break;
				case 2:
				case 3:
					SaveToCsv(saveFileDialog.FileName, seriesList);
					break;
				}
				_Chart.Cursor = Cursors.Arrow;
				MessageBox.Show(Utility.GetMessage("msg_data_export_sussess"));
			}
		}
		/// <summary>
		/// 保存曲线数据到Excel
		/// </summary>
		/// <param name="file"></param>
		/// <param name="seriesList"></param>
		private void SaveToExcel(string file, List<XYSeriesEx> seriesList)
		{
			List<int> list = seriesList.Select((XYSeriesEx s) => s.Channel).Distinct().ToList();
			using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(file, SpreadsheetDocumentType.Workbook))
			{
				spreadsheetDocument.AddWorkbookPart();
				spreadsheetDocument.WorkbookPart.Workbook = new Workbook();
				spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
				foreach (int channel in list)
				{
					WorksheetPart worksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
					worksheetPart.Worksheet = new Worksheet();
					SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
					uint num = 1u;
					Row row = new Row();
					row.RowIndex = num++;
					Row row2 = row;
					Cell cell = null;
					if (seriesList.Count > 0)
					{
						Cell cell2 = new Cell();
						cell2.CellValue = new CellValue("");
						cell = cell2;
						row2.Append(cell);
						foreach (XYDataPoint point in seriesList[0].Points)
						{
							Cell cell3 = new Cell();
							cell3.CellValue = new CellValue(point.ValueX.ToString());
							cell = cell3;
							row2.Append(cell);
						}
					}
					sheetData.Append(row2);
					List<XYSeriesEx> list2 = seriesList.Where((XYSeriesEx s) => s.Channel == channel).ToList();
					foreach (XYSeriesEx item in list2)
					{
						Row row3 = new Row();
						row3.RowIndex = num++;
						row2 = row3;
						Cell cell4 = new Cell();
						cell4.CellValue = new CellValue(item.Well);
						cell4.DataType = CellValues.String;
						cell = cell4;
						row2.Append(cell);
						foreach (XYDataPoint point2 in item.Points)
						{
							Cell cell5 = new Cell();
							cell5.CellValue = new CellValue(point2.ValueY.ToString());
							cell = cell5;
							row2.Append(cell);
						}
						sheetData.Append(row2);
					}
					worksheetPart.Worksheet.Save();
					Sheets firstChild = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>();
					Sheet sheet = new Sheet
					{
						Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
						SheetId = (uint)channel
					};
					string message = Utility.GetMessage("Channel");
					int num2 = channel;
					sheet.Name = message + num2;
					firstChild.AppendChild(sheet);
				}
				spreadsheetDocument.WorkbookPart.Workbook.Save();
			}
		}

		/// <summary>
		/// 保存为csv文件
		/// </summary>
		/// <param name="file"></param>
		/// <param name="seriesList"></param>
		private void SaveToCsv(string file, List<XYSeriesEx> seriesList)
		{
			seriesList.Select((XYSeriesEx s) => s.Channel).Distinct().ToList();
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = null;
			stringBuilder2 = new StringBuilder();
			stringBuilder2.Append(Utility.GetMessage("reaction_well"));
			stringBuilder2.Append(",");
			stringBuilder2.Append(Utility.GetMessage("Channel"));
			if (seriesList.Count > 0)
			{
				foreach (XYDataPoint point in seriesList[0].Points)
				{
					stringBuilder2.Append(",");
					stringBuilder2.Append(point.ValueX);
				}
			}
			stringBuilder.AppendLine(stringBuilder2.ToString());
			IList<IGrouping<string, XYSeriesEx>> list = (from s in seriesList
				group s by s.Well).ToList();
			foreach (IGrouping<string, XYSeriesEx> item in list)
			{
				for (int i = 0; i < item.Count(); i++)
				{
					stringBuilder2 = new StringBuilder();
					XYSeriesEx xYSeriesEx = item.ElementAt(i);
					stringBuilder2 = new StringBuilder();
					if (i == 0)
					{
						stringBuilder2.Append(item.FirstOrDefault().Well);
					}
					stringBuilder2.Append(",");
					stringBuilder2.Append(xYSeriesEx.Channel);
					foreach (XYDataPoint point2 in xYSeriesEx.Points)
					{
						stringBuilder2.Append(",");
						stringBuilder2.Append(point2.ValueY.ToString("0.00000"));
					}
					stringBuilder.AppendLine(stringBuilder2.ToString());
				}
			}
			File.WriteAllText(file, stringBuilder.ToString(), Encoding.UTF8);
		}

		protected void ChangeCurveStyle_Click(object sender, EventArgs e)
		{
			RaiseChangeCurveStyle(new SelectedSeriesChangedArgs
			{
				SelectedSeries = SelectedSerie
			});
		}

		protected void Zoom_Click(object sender, EventArgs e)
		{
			AxisZoomWindow axisZoomWindow = new AxisZoomWindow();
			axisZoomWindow.Owner = Utility.GetMainWindow();
			axisZoomWindow.Chart = this;
			axisZoomWindow.viewChangeByLinearType();
			axisZoomWindow.ShowDialog();
		}

		private void SaveImage_Click(object sender, EventArgs e)
		{
			Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();
			saveFileDialog.InitialDirectory = Utility.GetMyDocumentFolder();
			saveFileDialog.Filter = string.Format("{1}{0}|*.{1}|{2}{0}|*.{2}|{3}{0}|*.{3}", Utility.GetMessage("File"), "png", "jpg", "bmp");
			if (saveFileDialog.ShowDialog() == true)
			{
				switch (saveFileDialog.FilterIndex)
				{
				case 1:
					SaveAsImage(saveFileDialog.FileName, ImageFormat.Png);
					break;
				case 2:
					SaveAsImage(saveFileDialog.FileName, ImageFormat.Jpeg);
					break;
				case 3:
					SaveAsImage(saveFileDialog.FileName, ImageFormat.Bmp);
					break;
				}
				MessageBox.Show(Utility.GetMessage("msg_saveimage_sussess"));
			}
		}
		/// <summary>
		/// 复制图像
		/// </summary>
		private void CopyToClipboard_Click(object sender, EventArgs e)
		{
			_Chart.CopyToClipboard();
		}

		private void Print_Click(object sender, EventArgs e)
		{
			if (MessageBox.Show(Utility.GetMessage("Msg_Print_Confirm"), Utility.GetMessage("Warning"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.No)
			{
				if (printdialog == null)
				{
					printdialog = new PrintDialog();
					printdialog.PrinterSettings.DefaultPageSettings.Landscape = true;
				}
				if (printer == null)
				{
					printer = new PrinterSettings();
					printer.DefaultPageSettings.Landscape = true;
				}
				if (page == null)
				{
					page = new PageSettings(printer);
					page.Landscape = true;
				}
				if (myPrintDoc == null)
				{
					myPrintDoc = new PrintDocument();
					myPrintDoc = _Chart.PrintDocument;
					myPrintDoc.DocumentName = "Slan";
					myPrintDoc.PrinterSettings = printer;
					myPrintDoc.DefaultPageSettings = page;
				}
				myPrintDoc.Print();
			}
		}
		/// <summary>
		/// 保存图像
		/// </summary>
		/// <param name="path"></param>
		public void SaveAsImage(string path)
		{
			SaveAsImage(path, ImageFormat.Png);
		}
		/// <summary>
		/// 保存图像
		/// </summary>
		/// <param name="path"></param>
		/// <param name="format"></param>
		public void SaveAsImage(string path, ImageFormat format)
		{
			_Chart.SaveTo(path, format);
		}

		public void Dispose()
		{
			if (graphics != null)
			{
				graphics.Dispose();
				graphics = null;
			}
			ContentMenu.Dispose();
			mToolTipManager.Dispose();
			Chart.Dispose();
		}

		public double GetLocationXData(int x)
		{
			double num = TransformXToData(x);
			if (num > GetCurrentMaxX())
			{
				return GetCurrentMaxX();
			}
			if (num < GetCurrentMinX())
			{
				return GetCurrentMinX();
			}
			return num;
		}

		public double GetLocationYData(int y)
		{
			double num = TransformYToData(y);
			if (num > GetCurrentMaxY())
			{
				return GetCurrentMaxY();
			}
			if (num < GetCurrentMinY())
			{
				return GetCurrentMinY();
			}
			return num;
		}

		public void SetCursor(Cursor cursor)
		{
			_Chart.Cursor = cursor;
		}

		public void UpdataAnnotationLocation(int x, int y)
		{
			if (boxAnnotation.Visible)
			{
				boxAnnotation.Location.LocationX = x;
				boxAnnotation.Location.LocationY = y;
			}
		}

		public void SetAnnotationText(string text, bool updateLoction = true)
		{
			boxAnnotation.Text = text;
			if (updateLoction)
			{
				Point point = _Chart.PointToClient(System.Windows.Forms.Control.MousePosition);
				SizeF sizeF = graphics.MeasureString(text, boxAnnotation.TextStyle.Font);
				UpdataAnnotationLocation(point.X - (int)sizeF.Width, point.Y + (int)(sizeF.Height / 2f));
			}
		}

		public void DisplayAnnotation(bool visible = true)
		{
			boxAnnotation.Visible = visible;
		}

		public void SetTitleX(string title)
		{
			_Chart.TitleBottom.Text = title;
		}

		public string GetTitleX()
		{
			return _Chart.TitleBottom.Text;
		}

		public void SetTitleY(string title)
		{
			_Chart.TitleLeft.Text = title;
		}

		public string GetTitleY()
		{
			return _Chart.TitleLeft.Text;
		}

		public virtual void SetXFormat(string format)
		{
			AxisX.Labels.ItemFormatString = "<DATA_VALUE:" + format + ">";
		}

		public virtual string GetXFormat()
		{
			return AxisX.Labels.ItemFormatString.Replace("<DATA_VALUE:", "").Replace(">", "");
		}

		public virtual void SetYFormat(string format)
		{
			AxisY.Labels.ItemFormatString = "<DATA_VALUE:" + format + ">";
		}

		public virtual string GetYFormat()
		{
			return AxisY.Labels.ItemFormatString.Replace("<DATA_VALUE:", "").Replace(">", "");
		}

		private void SelectedSeries(ISeries series)
		{
			if (series is XYSeriesEx && !((XYSeriesEx)series).Visible)
			{
				series = null;
			}
			if (series == null && SelectedSerie != null)
			{
				RaiseSelectedSeriesChanged(new SelectedSeriesChangedArgs
				{
					SelectedSeries = series,
					UnSelectedSeries = SelectedSerie
				});
				SelectedSerie = null;
			}
			if (series != null && series != SelectedSerie)
			{
				RaiseSelectedSeriesChanged(new SelectedSeriesChangedArgs
				{
					SelectedSeries = series,
					UnSelectedSeries = SelectedSerie
				});
				SelectedSerie = series;
			}
		}

		private void RaiseSelectedSeriesTooltips(XYDataPoint data)
		{
			if (SelectedSerie == null || !ShowToolTips)
			{
				return;
			}
			UltraToolTipInfo ultraToolTipInfo = new UltraToolTipInfo();
			ultraToolTipInfo.ToolTipTextStyle = ToolTipTextStyle.Raw;
			GetTooltipsArgs getTooltipsArgs = new GetTooltipsArgs();
			getTooltipsArgs.Series = SelectedSerie;
			getTooltipsArgs.DataPoint = data;
			GetTooltipsArgs getTooltipsArgs2 = getTooltipsArgs;
			RaiseGetTooltips(getTooltipsArgs2);
			if (getTooltipsArgs2.Handle)
			{
				return;
			}
			if (!string.IsNullOrEmpty(getTooltipsArgs2.Tooltips))
			{
				if (getTooltipsArgs2.Tooltips.Contains("#VAL{X}"))
				{
					string text = null;
					text = ((!string.IsNullOrEmpty(getTooltipsArgs2.FromatX)) ? data.ValueX.ToString(getTooltipsArgs2.FromatX) : FormatX(data.ValueX));
					getTooltipsArgs2.Tooltips = getTooltipsArgs2.Tooltips.Replace("#VAL{X}", text);
				}
				if (getTooltipsArgs2.Tooltips.Contains("#VALX{Y}"))
				{
					string text2 = null;
					text2 = ((!string.IsNullOrEmpty(getTooltipsArgs2.FromatY)) ? data.ValueY.ToString(getTooltipsArgs2.FromatY) : FormatY(data.ValueY));
					getTooltipsArgs2.Tooltips = getTooltipsArgs2.Tooltips.Replace("#VALX{Y}", text2);
				}
				ultraToolTipInfo.ToolTipText = getTooltipsArgs2.Tooltips;
			}
			else
			{
				ultraToolTipInfo.ToolTipText = GetDefaultTooltips(data);
			}
			mToolTipManager.Enabled = true;
			mToolTipManager.SetUltraToolTip(_Chart, ultraToolTipInfo);
			mToolTipManager.ShowToolTip(_Chart);
		}

		protected virtual string GetDefaultTooltips(XYDataPoint data)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(_Chart.TitleBottom.Text + ":" + data.ValueX.ToString(TooltipsFromatX));
			stringBuilder.AppendLine(_Chart.TitleLeft.Text + ":" + data.ValueY.ToString(TooltipsFromatY));
			return stringBuilder.ToString();
		}
	}
}
